package org.qpcr.community.project.service;

import lombok.extern.slf4j.Slf4j;
import org.hswebframework.ezorm.rdb.mapping.ReactiveQuery;
import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.hswebframework.web.exception.BusinessException;
import org.qpcr.community.project.model.entity.TestSequenceInstanceEntity;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Service
@Slf4j
public class LocalTestSequenceInstanceService extends GenericReactiveCrudService<TestSequenceInstanceEntity, String> {


    @Autowired
    private ReactiveRepository<TestSequenceInstanceEntity, String> repository;

    public Mono<TestSequenceInstanceEntity> findBySeqCode(String code) {
        return Mono.justOrEmpty(code).flatMap((_code) -> {
            return ((ReactiveQuery)this.repository.createQuery().where(TestSequenceInstanceEntity::getCode, _code)).fetchOne();
        });
    }
    public Mono<TestSequenceInstanceEntity> findBySeqCode(String code,String id) {
        return Mono.justOrEmpty(code).flatMap((_code) -> {
            return ((ReactiveQuery)this.repository.createQuery().where(TestSequenceInstanceEntity::getCode, _code).not(TestSequenceInstanceEntity::getId, id)).fetchOne();
        });
    }


    @Override
    public Mono<Integer> deleteById(Publisher<String> idPublisher) {
        return Flux.from(idPublisher)
            .flatMap(id ->
                isTempSeq(id)
                    .flatMap(isTemp -> {
                        if (isTemp) {
                            return Mono.error(new BusinessException("温度校准序列不能删除"));
                        }
                        return Mono.just(id);
                    })
            )
            .as(super::deleteById);
    }



    /**
     * 是否测温序列
     */
    public Mono<Boolean> isTempSeq(String id) {
        return createQuery()
            .is(TestSequenceInstanceEntity::getId,id)
            .and()
            .is(TestSequenceInstanceEntity::getName,"温度校准")
            .and()
            .is(TestSequenceInstanceEntity::getCode,"C0")
            .fetch()
            .collectList()
            .map(list -> !list.isEmpty());
    }

    @Override
    public Mono<Integer> updateById(String id, Mono<TestSequenceInstanceEntity> entityPublisher) {
        return isTempSeq(id)
            .flatMap(isTemp -> {
                if (!isTemp) {
                    return super.updateById(id, entityPublisher);
                }
                return entityPublisher.flatMap(entity -> {
                    boolean modifyName = entity.getName() != null && !"温度校准".equals(entity.getName());
                    boolean modifyCode = entity.getCode() != null && !"C0".equals(entity.getCode());
                    if (modifyName || modifyCode) {
                        return Mono.error(new BusinessException("温度校准序列的名称和编码不可修改"));
                    }
                    return super.updateById(id, Mono.just(entity));
                });
            });
    }
}
